package org.lex.expression;


public class Operator implements Element {
	private int priority = 0;
	private String image = "";
	private TokenType tokenType = null;

	public Operator(Token token) {
		this.image = token.getImage();
		this.tokenType = token.getTokenType();
		this.priority = OperatorPriority.getPriority(tokenType);
	}

	public int getPriority() {
		return this.priority;
	}

	public TokenType getTokenType() {
		return tokenType;
	}

	public String getImage() {
		return this.image;
	}

	public boolean isOperand() {
		return false;
	}

	public boolean isOperator() {
		return true;
	}

	public String toString() {
		return this.tokenType.toString();
	}

	public Operand operate(Operand first, Operand second) {
		if (null == first || null == second || Operand.NA == first || Operand.NA == second)
			return Operand.NA;
		return new Operand(operate(first.getValue(), second.getValue()));
	}

	public Number operate(Number first, Number second) {
		double a = first.doubleValue();
		double b = second.doubleValue();
		double result = 0.0D;
		switch (this.tokenType) {
		case ADD:
			result = a + b;
			break;
		case MINUS:
			result = a - b;
			break;
		case MULTIPLY:
			result = a * b;
			break;
		case DIVIDE:
			if (0.0D == b)
				return Double.NaN;
			result = a / b;
			break;
		case MOD:
			result = a % b;
			break;
		case POWER:
			result = Math.pow(a, b);
			break;
		default:
			return Double.NaN;
		}
		return result;
	}

	static class OperatorPriority {
		// ���������ȼ�����ֵԽ�����ȼ�Խ��
		static int getPriority(TokenType tokenType) {
			switch (tokenType) {
			case ADD:
				return 10;
			case MINUS:
				return 10;
			case MULTIPLY:
				return 20;
			case DIVIDE:
				return 20;
			case MOD:
				return 20;
			case POWER:
				return 30;
			default:
				return 0;
			}
		}
	}
}
